From 4032ebdf0914314e6f01a8968a344c60455f73a2 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 17 May 2006 23:51:39 +0100 Subject: [PATCH] SVM patch to reverse the logic of the general1 intercepts for easier reading, also add the INVD intercept with print/eip increment only. Signed-off-by: Tom Woller Signed-off-by: Mats Petersson --- xen/arch/x86/hvm/svm/svm.c | 30 ++++++++++++++++++++++++++---- xen/arch/x86/hvm/svm/vmcb.c | 16 ++++++---------- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index e95cafd9a0..cf84b2fabf 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -1852,7 +1852,8 @@ static int svm_cr_access(struct vcpu *v, unsigned int cr, unsigned int type, break; case INSTR_SMSW: - svm_dump_inst(svm_rip2pointer(vmcb)); + if (svm_dbg_on) + svm_dump_inst(svm_rip2pointer(vmcb)); value = v->arch.hvm_svm.cpu_shadow_cr0; gpreg = decode_src_reg(prefix, buffer[index+2]); set_reg(gpreg, value, regs, vmcb); @@ -1989,9 +1990,25 @@ static inline void svm_vmexit_do_hlt(struct vmcb_struct *vmcb) } -static inline void svm_vmexit_do_mwait(void) +static void svm_vmexit_do_invd(struct vmcb_struct *vmcb) { -} + int inst_len; + + /* Invalidate the cache - we can't really do that safely - maybe we should + * WBINVD, but I think it's just fine to completely ignore it - we should + * have cache-snooping that solves it anyways. -- Mats P. + */ + + /* Tell the user that we did this - just in case someone runs some really weird + * operating system and wants to know why it's not working as it should... + */ + printk("INVD instruction intercepted - ignored\n"); + + inst_len = __get_instruction_length(vmcb, INSTR_INVD, NULL); + __update_guest_eip(vmcb, inst_len); +} + + #ifdef XEN_DEBUGGER @@ -2053,7 +2070,7 @@ void svm_handle_invlpg(const short invlpga, struct cpu_user_regs *regs) __update_guest_eip(vmcb, inst_len); /* - * The address is implicit on this instruction At the moment, we don't + * The address is implicit on this instruction. At the moment, we don't * use ecx (ASID) to identify individual guests pages */ g_vaddr = regs->eax; @@ -2703,6 +2720,11 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs regs) raise_softirq(SCHEDULE_SOFTIRQ); break; + + case VMEXIT_INVD: + svm_vmexit_do_invd(vmcb); + break; + case VMEXIT_GDTR_WRITE: printk("WRITE to GDTR\n"); break; diff --git a/xen/arch/x86/hvm/svm/vmcb.c b/xen/arch/x86/hvm/svm/vmcb.c index 91697b9064..4a61ff62be 100644 --- a/xen/arch/x86/hvm/svm/vmcb.c +++ b/xen/arch/x86/hvm/svm/vmcb.c @@ -117,16 +117,12 @@ static int construct_vmcb_controls(struct arch_svm_struct *arch_svm) /* mask off all general 1 intercepts except those listed here */ vmcb->general1_intercepts = - ~(GENERAL1_INTERCEPT_CR0_SEL_WRITE | GENERAL1_INTERCEPT_VINTR | - GENERAL1_INTERCEPT_IDTR_READ | GENERAL1_INTERCEPT_IDTR_WRITE | - GENERAL1_INTERCEPT_GDTR_READ | GENERAL1_INTERCEPT_GDTR_WRITE | - GENERAL1_INTERCEPT_LDTR_READ | GENERAL1_INTERCEPT_LDTR_WRITE | - GENERAL1_INTERCEPT_TR_READ | GENERAL1_INTERCEPT_TR_WRITE | - GENERAL1_INTERCEPT_RDTSC | GENERAL1_INTERCEPT_PUSHF | - GENERAL1_INTERCEPT_SWINT | GENERAL1_INTERCEPT_POPF | - GENERAL1_INTERCEPT_IRET | GENERAL1_INTERCEPT_PAUSE | - GENERAL1_INTERCEPT_TASK_SWITCH - ); + GENERAL1_INTERCEPT_INTR | GENERAL1_INTERCEPT_NMI | + GENERAL1_INTERCEPT_SMI | GENERAL1_INTERCEPT_INIT | + GENERAL1_INTERCEPT_CPUID | GENERAL1_INTERCEPT_INVD | + GENERAL1_INTERCEPT_HLT | GENERAL1_INTERCEPT_INVLPG | + GENERAL1_INTERCEPT_INVLPGA | GENERAL1_INTERCEPT_IOIO_PROT | + GENERAL1_INTERCEPT_MSR_PROT | GENERAL1_INTERCEPT_SHUTDOWN_EVT; /* turn on the general 2 intercepts */ vmcb->general2_intercepts = -- 2.30.2